//
// Created by 匡涂上青 on 2021/6/18.
//

#ifndef CSUGL_SHADER_H
#define CSUGL_SHADER_H

#include "../core/core.h"

#include "../vendor/glm/glm/glm.hpp"
#include <string>

namespace csugl {
    class Shader {
    public:
        Shader(const std::string &filePath);
        
        Shader(const std::string &vsPath,const std::string &fsPath);

        Shader(const std::string &vsPath,const std::string &fsPath, const std::string &gsPath);

        ~Shader();

        void use() const;

        void un_use() const;

        [[nodiscard]] const std::string &get_name() const { return m_Name; }

        void set_name(const std::string &name) { m_Name = name; }

    public:
        void set_bool(const std::string &name, bool value) const;

        void set_int(const std::string &name, int value) const;

        void set_float(const std::string &name, float value) const;

        void set_vec2(const std::string &name, const glm::vec2 &value) const;

        void set_vec3(const std::string &name, const glm::vec3 &value) const;

        void set_vec4(const std::string &name, const glm::vec4 &value) const;

        void set_rgba(const std::string &name, const glm::vec4 &color) const;

        void set_rgb(const std::string &name, const glm::vec3 &color) const;

        void set_mat4(const std::string &name, const glm::mat4 &mat) const;

        void set_sampler2D(const std::string &name, int index) const;

        void set_floatArray(const std::string &name, size_t size, const float *data) const;

        void set_intArray(const std::string &name, size_t size, const int *data) const;

    private:
        /// <summary>
        /// Get property ID by shaderID and property name
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [[nodiscard]] int GetPropertyID(const std::string &name) const;

    private:
        /// <summary>
        /// id of shader program
        /// </summary>
        unsigned int m_ID;

        std::string m_Name;

    public:
        static Ref<Shader> Create(const std::string &filePath) {
            return csugl::MakeRef<Shader>(filePath);
        }
        
        static Ref<Shader> Create(const std::string &vsPath,const std::string &fsPath) {
            return csugl::MakeRef<Shader>(vsPath, fsPath);
        }

        static Ref<Shader> Create(const std::string &vsPath,const std::string &fsPath, const std::string &gsPath) {
            return csugl::MakeRef<Shader>(vsPath, fsPath, gsPath);
        }
    };
}


#endif //CSUGL_SHADER_H
